package serialUtility



import (
	"log"
	"serialServer/utility"
	"github.com/jacobsa/go-serial/serial"
	"io"
	"serialServer/mysqlUtility"
	"math/rand"
	"time"
	"fmt"
)

var SerialPort io.ReadWriteCloser

//func init()  {
//
//}
func ConnectToSerialPort(config utility.SerialConfig) {
	// Set up options.
	options := serial.OpenOptions{
		PortName:config.Name,
		BaudRate: config.Baud,
		DataBits: 13, // 13位长，十二位有效位和一个bit的校检位
		StopBits: 1,
		MinimumReadSize: 4,
	}

	// Open the port.
	var err error
	SerialPort, err = serial.Open(options)
	if err != nil {
		log.Fatalf("serial.Open: %v", err)
	}
}

func ReadDataToDb() bool {

	buf := make([]byte, 13)

	for {
		SerialPort.Read(buf)
		if RedundancyCheck(buf) {
			ParseBufToRecordAndInsert(buf)
		} else {
			continue
		}
	}
}

func ReadDataToDbMock() bool {

	for {
		deviceId := "aaa"
		uuidStr := utility.GetUuid()

		var thermocouple utility.Thermocouple
		thermocouple.DeviceId = deviceId
		thermocouple.Uuid = uuidStr
		//record.Type = "thermocouple" // 热电偶温度计
		thermocouple.Value = rand.Float32() * 100
		mysqlUtility.InsertIntoThermocouple(thermocouple)

		var accelerometer utility.Accelerometer
		accelerometer.DeviceId = deviceId
		accelerometer.Uuid = uuidStr
		//record.Type = "accelerometer" // 加速度计
		accelerometer.AcceRx = rand.Float32() * 100
		accelerometer.AcceRy = rand.Float32() * 100
		accelerometer.AcceRz = rand.Float32() * 100
		mysqlUtility.InsertIntoAccelerometer(accelerometer)

		var gyroscope utility.Gyroscope
		gyroscope.DeviceId = deviceId
		gyroscope.Uuid = uuidStr
		//record.Type = "gyroscope" // 陀螺仪
		gyroscope.GyroRx = rand.Float32() * 100
		gyroscope.GyroRy = rand.Float32() * 100
		gyroscope.GyroRz = rand.Float32() * 100
		mysqlUtility.InsertIntoGyroscope(gyroscope)

		var magnetic utility.Magnetic
		magnetic.DeviceId = deviceId
		magnetic.Uuid = uuidStr
		//record.Type = "magnetic" // 地磁感应计
		magnetic.MegnX = rand.Float32() * 100
		magnetic.MegnY = rand.Float32() * 100
		magnetic.MegnZ = rand.Float32() * 100
		mysqlUtility.InsertIntoMagnetic(magnetic)

		var barometer utility.Barometer
		barometer.DeviceId = deviceId
		barometer.Uuid = uuidStr
		//record.Type = "barometer" // 气压计
		barometer.Value = rand.Float32() * 100
		mysqlUtility.InsertIntoBarometer(barometer)

		var electricResistance utility.ElectricResistance
		electricResistance.DeviceId = deviceId
		electricResistance.Uuid = uuidStr
		//record.Type = "electricResistance" // 电阻应变片
		electricResistance.Value = rand.Float32() * 100
		mysqlUtility.InsertIntoElectricResistance(electricResistance)
		fmt.Println("insert db")
		time.Sleep(3000 * time.Millisecond)
	}
}

func CloseSerialPort() {
	SerialPort.Close()
}

func RedundancyCheck(buf []byte) bool {
	var check byte
	for i := 0; i < len(buf) - 1; i++ {
		check &= buf[i]
	}
	if check == buf[len(buf) - 1] {
		return true
	} else {
		return  false
	}
}

func ParseBufToRecordAndInsert(buf []byte) bool {
	sensorType := buf[4] << 8 + buf[5];
	payload := buf[6: 12]
	mcuId := buf[2] << 8 + buf[3];

	deviceId := string(mcuId)
	uuidStr := utility.GetUuid()


	switch sensorType {
	case 0x0001:
		var record utility.Thermocouple
		record.DeviceId = deviceId
		record.Uuid = uuidStr
		//record.Type = "thermocouple" // 热电偶温度计
		temp := payload[0] << 24;
		temp += payload[1] << 16;
		temp += payload[2] << 8;
		temp += payload[3];

		record.Value = float32(int32(temp))
		mysqlUtility.InsertIntoThermocouple(record)
	case 0x0002:
		var record utility.Accelerometer
		record.DeviceId = deviceId
		record.Uuid = uuidStr
		//record.Type = "accelerometer" // 加速度计
		acceX := payload[0] << 8;
		acceX += payload[1];
		acceY := payload[2] << 8;
		acceY += payload[3];
		acceZ := payload[4] << 8;
		acceZ += payload[5];

		acceRx :=  float32(int32(acceX)) / 16384.0;
		acceRy :=  float32(int32(acceY)) / 16384.0;
		acceRz :=  float32(int32(acceZ)) / 16384.0;

		record.AcceRx = acceRx
		record.AcceRy = acceRy
		record.AcceRz = acceRz
		mysqlUtility.InsertIntoAccelerometer(record)
	case 0x0004:
		var record utility.Gyroscope
		record.DeviceId = deviceId
		record.Uuid = uuidStr
		//record.Type = "gyroscope" // 陀螺仪
		gyroX := payload[0] << 8;
		gyroX += payload[1];
		gyroY := payload[2] << 8;
		gyroY += payload[3];
		gyroZ := payload[4] << 8;
		gyroZ += payload[5];

		gyroRx := float32(int32(gyroX)) / 16.4;
		gyroRy := float32(int32(gyroY)) / 16.4;
		gyroRz := float32(int32(gyroZ)) / 16.4;

		record.GyroRx = gyroRx
		record.GyroRy = gyroRy
		record.GyroRz = gyroRz
		mysqlUtility.InsertIntoGyroscope(record)
	case 0x0008:
		var record utility.Magnetic
		record.DeviceId = deviceId
		record.Uuid = uuidStr
		//record.Type = "magnetic" // 地磁感应计
		megnX := payload[0] << 8;
		megnX += payload[1];
		megnY := payload[2] << 8;
		megnY += payload[3];
		megnZ := payload[4] << 8;
		megnZ += payload[5];
		record.MegnX = float32(int32(megnX))
		record.MegnY = float32(int32(megnY))
		record.MegnZ = float32(int32(megnZ))
		mysqlUtility.InsertIntoMagnetic(record)
	case 0x0010:
		var record utility.Barometer
		record.DeviceId = deviceId
		record.Uuid = uuidStr
		//record.Type = "barometer" // 气压计
		press := payload[0] << 24;
		press += payload[1] << 16;
		press += payload[2] << 8;
		press += payload[3];
		p := float32(int32(press)) / 100.0;
		record.Value = p
		mysqlUtility.InsertIntoBarometer(record)
	case 0x0020:
		var record utility.ElectricResistance
		record.DeviceId = deviceId
		record.Uuid = uuidStr
		//record.Type = "electricResistance" // 电阻应变片
		strain := payload[0] << 24;
		strain += payload[1] << 16;
		strain += payload[2] << 8;
		strain += payload[3];
		var big = 2^23

		st := (1.0 / (2.048*float32(int32(strain))/ 3.3 / float32(big) + 1.0) - 1.0);
		st = st * float32(10^6);
		record.Value = st
		mysqlUtility.InsertIntoElectricResistance(record)
	}
	return true
}
